跳到主要内容

一、 可选链式操作符 (?.)

安全的访问可能是 nullundefined 的属性,避免了因链式访问导致的错误。

const user = { address: { street: 'China' } };

// 传统方式
console.log(user.address ? user.address.street : undefined); // "China"

// Optional Chaining
console.log(user.address?.street); // "China"

// 当地址不存在时
const user2 = { name: 'Tom' };

console.log(user2.address?.street); // undefined

二、 空值合并操作符 (??

仅在左操作符为 nullundefined 时提供默认值。

const a = undefined;

const b = a ?? 'Tom';

console.log(b); // 'Tom'

三、 动态 import(dynamic import)

允许在运行时通过 import() 函数动态加载模块,返回一个 Promise (支持代码分割和按需加载)

  • 减少初始加载体积,提升页面性能(尤其适用于大型应用)
// 传统的静态导入:编译时加载,无论是否使用都会加载
import { utils } from './utils.js';

// 动态导入:运行时加载(如用户点击按钮时)
button.addEventListener('click', async () => {
/** 获取异步的模块 */
const module = await import('./utils.js');
module.utils.doMoreThing();
});

四、 BigInt 大整数类型

解决 JavaScript 中 Number 类型无法精确到表示超过 2 ** 53 - 1 (Number.MAX_SAFE_INTEGER) 的整数问题。

  • 在数字后添加 n (如 123n
  • 使用 BigInt() 构造函数(如 BigInt(123)
// Number类型的精度问题
console.log(9007199254740992 === 9007199254740993); // true(错误,本应不等)

// BigInt解决精度问题
const bigNum1 = 9007199254740992n;
const bigNum2 = 9007199254740993n;
console.log(bigNum1 === bigNum2); // false(正确)
注意
  • BigInt 不能直接与 Number 运算,需要显式转化
  • 不支持 Math 对象的方法(如 Math.sqrt(4n) 将报错)

五、 String.prototype.matchAll()

String.prototype.matchAll() 将返回一个迭代器,包含字符串中所有的正则表达式的匹配结果(包括捕获组),解决 match() 无法获取所有捕获组的问题。

const str = 'a1b2c3';
const regex = /(\w)(\d)/g;

// 传统match():只能获取匹配的整体,丢失捕获组
console.log(str.match(regex)); // ["a1", "b2", "c3"]

// matchAll():获取所有匹配及捕获组
for (const match of str.matchAll(regex)) {
console.log(match);
// 输出:
// ["a1", "a", "1", index: 0, input: "a1b2c3", groups: undefined]
// ["b2", "b", "2", index: 2, input: "a1b2c3", groups: undefined]
// ["c3", "c", "3", index: 4, input: "a1b2c3", groups: undefined]
}

六、 globalThis 统一全局对象访问

解决不同的环境下全局对象的不一致问题

  • 浏览器: window
  • Node.js:global
  • Web Worker:self
// 访问全局对象

// 在浏览器环境

七、 Promise.allSettled()

Promise.allSettled() 接受一个 Promise 数组,当所有的 Promise 都‘已决’(settled,无论成功 fulfilled 还是失败 rejected)时,返回一个新的 Promise ,结果包含每个 Promise 的状态和值。

信息

Promise.all() 是若是串联,当任意一个 Promise 失败时立即 reject,而 allSettled() 将等待所有的操作完成。

const promises = [
Promise.resolve('成功1'),
Promise.reject('失败1'),
Promise.resolve('成功2'),
];

// 等待所有Promise完成(无论成功/失败)
Promise.allSettled(promises).then(results => {
results.forEach(result => {
if (result.status === 'fulfilled') {
console.log('成功:', result.value);
} else {
console.log('失败:', result.reason);
}
});
});

八、 模块化命名空间导出优化: export * as xx from "xxx module"

简化了模块的命名空间导出语法,无需先导入然后再导出。

// 传统写法:先导出再导出
import * as utils from './utils.js';
export { utils };

// ES2020 简化式写法
export * as utils from './utils.js';

九、 模块的元信息 import.meta

提供了 import.meta 来访问模块的元信息,目前主要支持 import.meta.url ,返回当前文件的 URL。

十、 for-in 枚举顺序标准化

此前,for-in 循环的枚举顺序未明确,不同的引擎实现不一致。ES2020 规范了枚举顺序:

  • 先遍历对象自身的可枚举属性(按创建顺序)
  • 再遍历原型链上的可枚举属性(按创建顺序)
  • 忽略 Symbol 类型的属性